<?php
/**
 * yii 本身提供了Redis插件，有 yii\redis\Connection 和 yii\redis\Cache 但都不好用。
 *
 * redis 本身是有 [php 扩展](https://williamsrobyn.files.wordpress.com/2014/05/save-rock-and-roll.png) 的，
 * 它提供了良好的API和完善的文档。
 * OriginRedis 就是对其进行简单的封装。
 *
 * @author liuqing@knowbox.cn at 2017-01-13
 */

namespace components;

use Redis;
use Exception;

class RedisExtend extends Base
{
    // redis连接
    private $_socket = null;

    public $hostname = '127.0.0.1';// string. can be a host, or the path to a unix domain socket 
    public $port = 6379;// int, optional 
    public $timeout = 0;// float, value in seconds (optional, default is 0 meaning unlimited) 
    public $reserved = null;// should be NULL if retry_interval is specified 
    public $retryinterval = 1000;// int, value in milliseconds (optional)
    public $database = 0;

    public function __construct(Array $config = []){
        isset($config['hostname'])      && $this->hostname      = $config['hostname'];
        isset($config['port'])          && $this->port          = $config['port'];
        isset($config['timeout'])       && $this->timeout       = $config['timeout'];
        isset($config['retryinterval']) && $this->retryinterval = $config['retryinterval'];
        isset($config['database'])      && $this->database      = $config['database'];
        $this->open();
    }
    /**
     * 建立redis连接
     *
     * @param host: string. can be a host, or the path to a unix domain socket 
     * @param port: int, optional 
     * @param timeout: float, value in seconds (optional, default is 0 meaning unlimited) 
     * @param reserved: should be NULL if retry_interval is specified 
     * @param retry_interval: int, value in milliseconds (optional)
     */
    public function open()
    {
        if(! empty($this->_socket)) {
            return;
        }

        $this->_socket = new Redis();
        //还有pconnect 进行持久化连接，但是不需要
        $this->_socket->connect($this->hostname, $this->port, $this->timeout, 
            $this->reserved, $this->retryinterval);
        $this->_socket->select($this->database);
    }

    /**
     * 使用类似 Trait 的方式进行横向扩展，类似于 yii 的 Behavior
     */
    public function __call($name, $params) 
    {
        $this->open();

        if(method_exists($this->_socket, $name)) {
            return call_user_func_array([$this->_socket, $name], $params);
        }

        throw new Exception("Redis method not exist:". $name);
        
    }

    public function close()
    {
        if(!empty($this->_socket)) {
            $this->_socket->close();
        }
    }
}
